package services

import (
	"dahuang/models"
	"github.com/astaxie/beego/logs"
	"reflect"
	"time"
)

type systemCall struct {
	//定义内联语句,word=>callFnName
	innerWords map[string]string

	//定义系统调用请求次数
	callCnt map[string]*SysCallCnt

	//定义系统调用所携带参数
	callParams map[string]*SysCallParams

	//最后一次执行的系统调用名称
	lastCallFn string

	//最后一次执行call的时间
	lastCallTime time.Time
}

//系统调用次数
type SysCallCnt struct {
	Cnt int
	LastDate time.Time
}

var (
	//默认系统调用实例
	SystemCallDefault = systemCall{
		innerWords: make(map[string]string),
		callCnt:    make(map[string]*SysCallCnt),
		callParams: make(map[string]*SysCallParams),
	}
)

//初始化word
func (this *systemCall) InitWords() {
	//从数据库中加载数据
	this.innerWords = models.InnerWordAll()

	//第一次没有的时候预设一批数据
	if len(this.innerWords) == 0 {
		firstInnerWords := map[string]string{
			"几号了":"CallWhatDate",
			"今天几号了":"CallWhatDate",
			"今天星期几":"CallWhatDate",
			"昨天几号":"CallWhatDate",
			"今天什么日子":"CallWhatDate",
		}
		for key,val := range firstInnerWords  {
			models.InnerWordSet(key, val)
		}

		//再次读取
		this.innerWords = models.InnerWordAll()
	}
}

//设置文字内联
func (this *systemCall) SetInnerWord(word, fnName string) {
	this.innerWords[word] = fnName
	//同步到数据库
	models.InnerWordSet(word, fnName)
}

//获取文字内联系统调用
func (this *systemCall) GetInnerWordFn(word string) string {
	return this.innerWords[word]
}

//沟通
func (this *systemCall) Call(word string) string {
	logs.Info("question:", word)

	//正常理解
	var call = this.GetInnerWordFn(word)
	if call == "" {
		//判断是否有上一次的call，且时间没有超过一定限制
		if this.lastCallFn != "" && time.Now().Sub(this.lastCallTime) < time.Minute {
			call = this.lastCallFn
		}
	}

	//模糊匹配检测
	if call == "" {
		//todo 模糊匹配现有的innerWord
	}

	//再次检测是否识别
	if call == "" {
		models.OuterWordAdd(word)
		return "你说啥？没听懂"
	}

	//执行call
	v := reflect.ValueOf(this)
	mv := v.MethodByName(call)
	resv := mv.Call([]reflect.Value{reflect.ValueOf(word)})

	answer := resv[0].Interface().(string)
	err,_ := resv[1].Interface().(error)
	if err != nil {
		return "异常"
	}

	this.lastCallFn = call
	this.lastCallTime = time.Now()

	return answer
}

